package br.com.os2.pacemark.dao;

import br.com.os2.pacemark.model.Estado;
import br.com.os2.pacemark.model.Municipio;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 *
 * Classe MunicipioDAO, extende a classe DAOGenerico para obeter recursos de
 * conexão e excução de consultas e comandos.
 *
 * Responsável por gerenciar acesso ao banco de dados relacionados a Entidade
 * Municipio.
 *
 * @author Daniel
 *
 */
public class MunicipioDAO extends DAOGenerico {

    /**
     * Método para inserir um municipio.
     *
     * @param municipio Objeto municipio a ser inserido.
     *
     * @return boolean indica se o método foi executado com sucesso.
     *
     *
     */
    public boolean inserir(Municipio municipio) {

        municipio.setId(getNextId("municipios"));

        return executarComando("INSERT INTO municipios (id,nome, estado_id) VALUES (?,?,?)", municipio.getId(), municipio.getNome(), municipio.getEstado().getId());

    }

    /**
     * Método para atualizar informações de um municipio.
     *
     * @param municipio Objeto municipio a ser atualizado.
     * @return boolean indica se o método foi executado com sucesso
     *
     *
     */
    public boolean atualizar(Municipio municipio) {

        return executarComando("UPDATE municipios SET nome = ?, estado_id = ?"
                + "WHERE id = ?", municipio.getNome(), municipio.getEstado().getId(), municipio.getId());

    }

    /**
     * Método para excluir um municipio.
     *
     * @param municipio Objeto municipio a ser excluído.
     *
     * @return boolean indica se o método foi executado com sucesso
     *
     *
     */
    public boolean excluir(Municipio municipio) {

        return executarComando("DELETE FROM municipios WHERE id = ?", municipio.getId());

    }

    /**
     * Método para excluir um municipio.
     *
     * @param id ID do objeto a ser excluído
     *
     * @return boolean indica se o método foi executado com sucesso
     *
     *
     */
    public boolean excluir(int id) {

        return executarComando("DELETE FROM municipios WHERE id = ?", id);

    }

    /**
     * Método para buscar o municipio pelo ID
     *
     * @return Municipio correspondente ai ID, se não for encontrado retorna
     * null.
     *
     * @param id inteiro que representa o ID do municipio na tabela
     *
     *
     */
    public Municipio getById(int id) {

        ResultSet rs = executarConsulta("SELECT * FROM municipios WHERE id = ?", id);

        Municipio municipio = null;

        try {

            EstadoDAO estadoDAO = new EstadoDAO();
            
            if (rs.next()) {

                municipio = polularInformacoes(rs, estadoDAO);

            }

        } catch (SQLException ex) {

            System.err.println("ERRO AO BUSCAR MUNICIPIO POR ID");

        } finally {

            try {

                rs.close();
                connection.close();

            } catch (SQLException ex) {

            }

        }

        return municipio;

    }

    /**
     * Método para listagem de todos os municipios
     *
     * @return Retorna uma lista de municipios com o resultado da consulta
     *
     *
     */
    public List<Municipio> listar() {

        List<Municipio> municipios = new ArrayList<>();

        ResultSet rs = executarConsulta("SELECT * FROM municipios");

        try {

            //DAO necessário para a listagem
            EstadoDAO estadoDAO = new EstadoDAO();

            while (rs.next()) {

                municipios.add(polularInformacoes(rs, estadoDAO));

            }

        } catch (SQLException ex) {

            System.err.println("ERRO AO PERCORER RESULT_SET");

        } finally {

            try {

                rs.close();
                connection.close();

            } catch (SQLException ex) {

            }

        }

        return municipios;

    }

    /**
     * Método para listagem de municipios por estado.
     *
     * @param estado serve como parametro para filtrar as cidades
     *
     * @return Retorna uma lista de municipios com o resultado da consulta
     *
     *
     */
    public List<Municipio> listar(Estado estado) {

        List<Municipio> municipios = new LinkedList<>();

        ResultSet rs = executarConsulta("SELECT * FROM municipios WHERE estado_id = ?", estado.getId());

        try {

            while (rs.next()) {

                municipios.add(polularInformacoes(rs, estado));

            }

        } catch (SQLException ex) {

            System.err.println("ERRO AO PERCORER RESULT_SET");

        } finally {

            try {

                rs.close();
                connection.close();

            } catch (SQLException ex) {

            }

        }

        return municipios;

    }

    /**
     * Método para preencher informações de um municipio com resultados do banco
     * de dados.
     *
     * @param rs ResultSet com o resultado de uma consulta SQL
     *
     * @param estado estado do municipio a ser preenchido as informações
     *
     * @return Retorna um municipio populado com informações vindas do banco de
     * dados
     *
     *
     */
    public Municipio polularInformacoes(ResultSet rs, Estado estado) {

        Municipio municipio = new Municipio();

        try {

            municipio.setId(rs.getInt("id"));
            municipio.setNome(rs.getString("nome"));
            municipio.setEstado(estado);

        } catch (SQLException ex) {

            System.err.println("ERRO AO PULULAR MUNICIPIO");

        }

        return municipio;

    }
    
    /**
     * Método para preencher informações de um municipio com resultados do banco
     * de dados.
     *
     * @param rs ResultSet com o resultado de uma consulta SQL
     *
     * @param estadoDAO DAO de estado
     *
     * @return Retorna um municipio populado com informações vindas do banco de
     * dados
     *
     *
     */
    public Municipio polularInformacoes(ResultSet rs, EstadoDAO estadoDAO) {

        Municipio municipio = new Municipio();

        try {

            municipio.setId(rs.getInt("id"));
            municipio.setNome(rs.getString("nome"));
            municipio.setEstado(estadoDAO.getById(rs.getInt("estado_id")));

        } catch (SQLException ex) {

            System.err.println("ERRO AO PULULAR MUNICIPIO");

        }

        return municipio;

    }

}
